import axios from 'axios'
import {ElLoading, ElMessage, ElMessageBox, ElNotification} from 'element-plus'
import {getAccessToken, logOutRemoveCache} from "@/common/utils/cache";
import {saveAs} from 'file-saver'
import {closeLoading, loading, routerPush, urlFileSuffix} from "@/common/utils/kit";

//当前环境
const env = import.meta.env.VITE_ENV
const openConsole = env === 'dev'
console.log("ENV", env)

//是否显示重新登录
export let isReLogin = {show: false};

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'

// 创建axios实例
export const service = axios.create({
    baseURL: import.meta.env.VITE_API_URL, timeout: 24 * 60 * 60 * 1000
})
// request拦截器
service.interceptors.request.use(config => {
    config.headers["Token"] = getAccessToken();
    config.params = {
        //追加时间戳
        timestamp: new Date().getTime()
    }
    // if (openConsole) console.log('响应拦截器 config ===>' + JSON.stringify(config))

    return config
}, error => {
    // if (openConsole) console.log('响应拦截器 error ===>' + JSON.stringify(error))
    return Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use((res) => {
    // if (openConsole) console.log('响应拦截器 response ===>' + JSON.stringify(res))

    const closeError = (res.config.closeError && res.config.closeError == '1');
    const code = res.data.code || 200;
    const message = res.data.message

    // 二进制数据则直接返回
    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
        return res.data;
    }

    //错误
    if (code === 401) {
        if (!closeError) ElMessage({message: message, type: 'error'})
        return Promise.resolve(res.data)
    }

    //Token失效
    if (code === 410) {
        //console.log(" location.href ", location.href)
        //console.log(" location.href ",)
        if (!isReLogin.show && !location.href.includes("/login")) {
            isReLogin.show = true;
            if (!closeError) ElMessageBox.confirm('登录状态已过期，请重新登录', '系统提示', {
                confirmButtonText: '重新登录', type: 'warning', showCancelButton: false,
            }).then(() => {
                logOutRemoveCache()
                isReLogin.show = false;
                location.href = '/index';
            }).catch(() => {
                isReLogin.show = false;
            });
        }
        return Promise.reject('无效的会话，或者会话已过期，请重新登录。')
    }

    //错误
    if (code === 500) {
        if (!closeError) ElMessage({message: message, type: 'error'})
        return Promise.resolve(res.data)
    }

    //重复提交
    if (code === 600) {
        if (!closeError) ElMessage({message: message, type: 'warning'})
        return Promise.resolve(res.data)
    }

    //无法识别
    if (code !== 200) {
        if (!closeError) ElMessage({message: message, type: 'warning'})
        return Promise.resolve(res.data)
    }

    //返回响应内容data
    return Promise.resolve(res.data)
}, (error) => {
    // if (openConsole) console.log('响应拦截器 error ===>' + JSON.stringify(error))

    let {message, code} = error;
    if (code === "ERR_NETWORK") {
        message = "网路断开或者，服务正在更新，暂时无法访问。";
        routerPush("/errNetwork")
        return Promise.reject(error)
    } else if (message.includes("timeout")) {
        message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
        message = error.response.data.message ? error.response.data.message : "访问服务接口失败，返回状态码：" + message.substring(message.length - 3);
    }

    // closeError : 不进行统一报错提醒
    if (error.config.closeError && error.config.closeError == '1') return Promise.reject(error)

    // 统一报错提醒
    ElNotification.warning({title: message})
    return Promise.reject(error)

})

// 通用下载方法
let downloadLoadingInstance;

export function downloadGet(url, filename, config) {
    downloadLoadingInstance = ElLoading.service({text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)",})
    return service.get(url, {
        responseType: 'blob', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, ...config
    }).then(async (data) => {
        const blob = new Blob([data])
        console.log(blob)
        saveAs(blob, filename)
        downloadLoadingInstance.close();
    }).catch((r) => {
        console.error(r)
        ElMessage.error('下载文件出现错误，请联系管理员！')
        downloadLoadingInstance.close();
    })
}

export function downloadPost(url, filename) {
    return service.get(url, {
        responseType: 'blob', headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).then(async (data) => {
        const blob = new Blob([data])
        console.log(blob)
        saveAs(blob, filename)
    }).catch((r) => {
        console.error(r)
        ElMessage.error('下载文件出现错误，请联系管理员！')
    })
}

// 通用下载方法
export function downloadChrome(url, fileName) {
    loading("正在下载文件...")
    let fetchType =
        [".ical", ".csv", ".atom", ".rss", ".xml", ".txt", ".html",
            ".css", ".js", ".pdf", ".jpg", ".png", ".gif", ".bmp", ".mp3",
            ".mp4", ".wav", ".webm", ".avi", ".md", ".ttf", ".otf", ".woff", ".json", ".svg"]
    let fileSuffix = urlFileSuffix(url);

    if (fetchType.indexOf(fileSuffix) != -1) {
        fetch(url).then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            return response.blob();
        })
            .then(blob => {
                // 创建下载链接
                const a = document.createElement('a');
                const downloadUrl = window.URL.createObjectURL(blob);

                // 设置链接的下载属性和文件名
                a.href = downloadUrl;
                a.download = fileName; // 设置下载文件名

                // 将链接添加到页面并触发点击下载
                document.body.appendChild(a);
                a.click();

                // 释放 URL 对象
                window.URL.revokeObjectURL(downloadUrl);

                // 移除链接元素
                document.body.removeChild(a);
                closeLoading()
            })
            .catch(error => {
                console.error('There was a problem with the fetch operation:', error);
            });
    } else {
        // 创建下载链接
        const a = document.createElement('a');

        // 设置链接的下载属性和文件名
        a.href = url;
        a.download = fileName; // 设置下载文件名

        // 将链接添加到页面并触发点击下载
        document.body.appendChild(a);
        a.click();

        // 释放 URL 对象
        window.URL.revokeObjectURL(url);

        // 移除链接元素
        document.body.removeChild(a);
        closeLoading()
    }

}

export function postForm(url, data = {}, headers = {}, configOther = {}) {

    let config_ = {url, data, method: "post", ...configOther}

    config_.headers = {"Content-Type": "application/x-www-form-urlencoded", ...headers}

    return service(config_)

}

export function postDownload(url, data, headers = null) {

    let config = {url, data, method: "post", responseType: 'blob',}

    config.headers = {"Content-Type": "application/x-www-form-urlencoded",}

    if (headers) config.headers = headers;

    return service(config)

}

export function postJSON(url, data, headers = {}) {
    let config = {url, data, method: "post"}
    config.headers = headers;
    return service(config)

}

export default service
